#include <STC89C5xRC.H>
#define uchar unsigned char
    
// dth11, 根据dth11 datasheet,其数据口必须上拉
sbit Data=P0^1;

// max7219， p0作为非拓展ram用，需上拉, 此处接线采用p04, p05, p06
sbit DIN=P0^4;
sbit LOAD=P0^5;  // LOAD(CS)
sbit CLK=P0^6; 

// registry address
#define DECODE_MODE  0x09  
#define INTENSITY    0x0A   
#define SCAN_LIMIT   0x0B   
#define SHUT_DOWN    0x0C   
#define DISPLAY_TEST 0x0F   

// datasheet  0-9对应0-9，  15全灭， 0x80(1<<7)则小数点亮
uchar digits[9] = {0, 0, 0x80, 0, 15, 15, 0, 0x80, 0};

//  STC89C5xRC是 T/12 指令周期, 对于12MHZ晶振，一个机器周期为1us.   
// 这里只是大概值，偏差会很大。1.不是所有指令都是单周期的，2.以汇编实现以下逻辑则能展开出各种中间op
void DHT11_delay_us(uchar n)
{
    while(--n);
}

// 同上大致估算，时间不准确。
void DHT11_delay_ms(uchar z)
{
   uchar i,j;
   for(i=z;i>0;i--)
      for(j=117;j>0;j--);
}

void DHT11_start()
{
   Data=1;
   DHT11_delay_us(2);
   Data=0;
   DHT11_delay_ms(20);   
   Data=1;
   DHT11_delay_us(30);
}

uchar DHT11_rec_byte()   
{
  uchar i, dat=0;
  for(i=0;i<8;i++)    
   {          
      while(!Data); 
      DHT11_delay_us(8);     
      dat<<=1;           
      if(Data==1) dat+=1;
      while(Data);  
    }  
    return dat;
}

void DHT11_receive()     
{
    uchar R_H,R_L,T_H,T_L;
    uchar RH,RL,TH,TL;
    uchar revise; 
    DHT11_start();
    if(Data==0)
    {
        while(Data==0);     
        DHT11_delay_us(40);  
        R_H=DHT11_rec_byte();    
        R_L=DHT11_rec_byte();     
        T_H=DHT11_rec_byte();   
        T_L=DHT11_rec_byte();    
        revise=DHT11_rec_byte(); 

        DHT11_delay_us(25);   

        if((R_H+R_L+T_H+T_L)==revise)      
        {
            RH=R_H;
            RL=R_L;
            TH=T_H;
            TL=T_L;
        } 
				
        digits[8] = TH / 10;
        digits[7] = ((TH % 10) | 0x80);  //数字+小数点
        digits[6] = TL / 10;
        //digits[5] = 15;
        //digits[4] = 15;
        digits[3] = RH / 10;
        digits[2] = ((RH % 10) | 0x80);
        digits[1] = RL / 10;
    }
}

void Write7219(unsigned char address, unsigned char dat)
{  
    unsigned char i;
    LOAD=0;   
    for (i=0;i<8;i++)                   
    {  
       CLK=0;     
       DIN=(bit)(address&0x80); 
       address<<=1;            
       CLK=1;        
    }
    for (i=0;i<8;i++)              
    {  
       CLK=0;
       DIN=(bit)(dat&0x80);    
       dat<<=1; 
       CLK=1;      
    }
    LOAD=1;                      
}


void Initial7219(void)                
 
{
    Write7219(SHUT_DOWN,0x01);        
    Write7219(DISPLAY_TEST,0x00);   
    Write7219(DECODE_MODE,0xff);  
    Write7219(SCAN_LIMIT,0x07);   
    Write7219(INTENSITY,0x04);     
}


void main()
{
     uchar i;
     Initial7219();
     while(1){   
         for(i=1; i < 9; i++) Write7219(i, digits[i]);
         for(i=0; i<20; i++) DHT11_delay_ms(100); 	
         DHT11_receive();		
      }
}